/************************************************************
 * Project Name         [Thinking_In_Java]
 * File Name            [Example_03_Object_Copy.java]
 * Creation Date        [20-Jun-2014]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ************************************************************/
package pkg_04_reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 反射 - 对象拷贝
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 * 
 */
public class Example_03_Object_Copy {

	/**
	 * 对象拷贝方法
	 * 
	 * @param object
	 *            待拷贝的对象
	 * @return 拷贝生成的对象
	 * @throws Exception
	 */
	public Object copyObject(Object object) throws Exception {
		Object copiedObject = null;
		// 获得对象所属的Class类型
		Class<?> classType = object.getClass();
		// 构造新的对象
		copiedObject = classType.getConstructor(new Class[] {}).newInstance(
				new Object[] {});

		// 获得所有的属性(包括私有属性)
		Field[] fields = classType.getDeclaredFields();
		for (Field field : fields) {
			String fieldName = field.getName();
			String firstLetter = fieldName.substring(0, 1).toUpperCase();

			// 构建getters/setters方法名
			String gettersName = "get" + firstLetter + fieldName.substring(1);
			String settersName = "set" + firstLetter + fieldName.substring(1);

			// 构建getters/setters方法
			Method gettersMethod = classType.getMethod(gettersName);
			Method settersMethod = classType.getMethod(settersName,
					field.getType());

			// 调用getters/setters方法
			Object fieldValue = gettersMethod.invoke(object);// 从原始对象中获得属性值
			settersMethod.invoke(copiedObject, fieldValue);// 将值设置到新的对象中
		}

		return copiedObject;
	}

	/**
	 * 测试方法
	 * 
	 * @param args
	 *            命令行参数
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		Employee employee = new Employee();
		employee.setEmployeeId(1000001);
		employee.setName("Sean Yang");
		employee.setHireDate(new Date());
		System.out.println(employee);

		Employee copied = (Employee) new Example_03_Object_Copy()
				.copyObject(employee);
		if (employee.equals(copied)) {
			System.out.println(copied);
		}
	}
}

/**
 * 测试使用的类对象
 * 
 * @author 不落的太阳(Sean Yang)
 * @version 1.0
 * @since JDK 6
 */
class Employee {

	private long employeeId;
	private String name;
	private Date hireDate;

	/**
	 * 构造方法
	 */
	public Employee() {
		super();
	}

	/**
	 * 获得员工ID
	 * 
	 * @return 员工ID
	 */
	public long getEmployeeId() {
		return employeeId;
	}

	/**
	 * 设置员工ID
	 * 
	 * @param employeeId
	 */
	public void setEmployeeId(long employeeId) {
		this.employeeId = employeeId;
	}

	/**
	 * 获得员工姓名
	 * 
	 * @return 员工姓名
	 */
	public String getName() {
		return name;
	}

	/**
	 * 设置员工姓名
	 * 
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 获得雇佣日期
	 * 
	 * @return 雇佣日期
	 */
	public Date getHireDate() {
		return hireDate;
	}

	/**
	 * 设置雇佣日期
	 * 
	 * @param hireDate
	 */
	public void setHireDate(Date hireDate) {
		this.hireDate = hireDate;
	}

	/**
	 * hashCode方法
	 * 
	 * @return hashCode
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (int) (employeeId ^ (employeeId >>> 32));
		result = prime * result
				+ ((hireDate == null) ? 0 : hireDate.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	/**
	 * equals方法
	 * 
	 * @param obj
	 * @return equals比较结果
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Employee other = (Employee) obj;
		if (employeeId != other.employeeId)
			return false;
		if (hireDate == null) {
			if (other.hireDate != null)
				return false;
		} else if (!hireDate.equals(other.hireDate))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	/**
	 * toString方法
	 * 
	 * @return Employee的字符串表示
	 */
	@Override
	public String toString() {
		return "Employee [getEmployeeId()=" + getEmployeeId() + ", getName()="
				+ getName() + ", getHireDate()=" + getHireDate()
				+ ", hashCode()=" + hashCode() + "]";
	}

}